import type { AutoPagination, ISearchParams } from '../index'
import { PageManager } from '../../../../../lib/abstract/page_manager'
import { PageHandler } from '../../../../../lib/page_handler'
import { BaiduPageType } from '../../../../../lib/page_handler/platform/baidu/types'
import { ToolKit } from '../../../../../lib/utils/toolkit'
import {
  getCurrentURL,
  HOSTNAME,
  logger,
  SUPPORTED_PLATFORMS,
} from '../../../../../types/constants'
import { IPaginationLoadType } from '../index'
import { AutoPaginationBase } from './base'

// 这里不添加 pn 参数
// 【百度搜索】【网页】搜索参数
export type IBaiduWebSearchParams = Record<typeof BaiduWebSearchParams[keyof typeof BaiduWebSearchParams], string>
export enum BaiduWebSearchParams {
  Wd = 'wd',
  Base_query = 'base_query',
  Oq = 'oq',
  Tn = 'tn',
  Pn = 'pn',
  Ch = 'ch',
  Ie = 'ie',
  Usm = 'usm',
  Rsv_pq = 'rsv_pq',
  Rsv_t = 'rsv_t',
  Topic_pn = 'topic_pn',
}

// 【百度搜索】【资讯】搜索参数
export type IBaiduNewsSearchParams = Record<typeof BaiduNewsSearchParams[keyof typeof BaiduNewsSearchParams], string>
export enum BaiduNewsSearchParams {
  Wd = 'wd',
  Word = 'word',
  Tn = 'tn',
  Pn = 'pn',
  Cl = 'cl',
  Ie = 'ie',
  Rtt = 'rtt',
  Bsst = 'bsst',
  Rsv_dl = 'rsv_dl',
  X_bfe_rqs = 'x_bfe_rqs',
  X_bfe_tjscore = 'x_bfe_tjscore',
  Tngroupname = 'tngroupname',
  NewVideo = 'newVideo',
  Goods_entry_switch = 'goods_entry_switch',
}

export type IBaiduSearchParams = IBaiduWebSearchParams | IBaiduNewsSearchParams

export class AutoPaginationBaidu extends AutoPaginationBase {
  // @Decorators.Identity
  readonly name: string = 'AutoPaginationBaidu'
  // @Decorators.PublicState
  private static instance: AutoPaginationBaidu
  // @Decorators.Dependency
  private readonly pageHandler: PageHandler = PageHandler.getInstance()
  private readonly pageManager: PageManager = PageManager.getInstance()
  // @Decorators.Config
  readonly pageType: BaiduPageType | 'default' = this.pageHandler.pages.baidu.pageType
  readonly loadType: IPaginationLoadType = this.pageType === BaiduPageType.Web ? IPaginationLoadType.Item : IPaginationLoadType.Pagination

  get defaultResultNum(): number { // 默认每页结果数量
    return this.pageManager.getSearchResultNum()
  }

  // 搜索链接默认参数值
  private get defaultSearchParam(): ISearchParams {
    return this.getSearchParams()
  }

  // 搜索链接默认参数值
  readonly defaultWebSearchParams: IBaiduWebSearchParams = {
    [BaiduWebSearchParams.Wd]: '',
    [BaiduWebSearchParams.Base_query]: '',
    [BaiduWebSearchParams.Oq]: '',
    [BaiduWebSearchParams.Tn]: '',
    [BaiduWebSearchParams.Pn]: '',
    [BaiduWebSearchParams.Ie]: 'utf-8',
    [BaiduWebSearchParams.Ch]: '',
    [BaiduWebSearchParams.Usm]: '3',
    [BaiduWebSearchParams.Rsv_pq]: '',
    [BaiduWebSearchParams.Rsv_t]: '',
    [BaiduWebSearchParams.Topic_pn]: '',
  }

  readonly defaultNewsSearchParams: IBaiduNewsSearchParams = {
    [BaiduNewsSearchParams.Wd]: '',
    [BaiduNewsSearchParams.Word]: '',
    [BaiduNewsSearchParams.Tn]: 'news',
    [BaiduNewsSearchParams.Pn]: '',
    [BaiduNewsSearchParams.Ie]: 'utf-8',
    [BaiduNewsSearchParams.Cl]: '2',
    [BaiduNewsSearchParams.Rtt]: '1',
    [BaiduNewsSearchParams.Bsst]: '1',
    [BaiduNewsSearchParams.Rsv_dl]: 'news_b_pn',
    [BaiduNewsSearchParams.X_bfe_rqs]: '',
    [BaiduNewsSearchParams.X_bfe_tjscore]: '',
    [BaiduNewsSearchParams.Tngroupname]: '',
    [BaiduNewsSearchParams.NewVideo]: '',
    [BaiduNewsSearchParams.Goods_entry_switch]: '',
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): AutoPaginationBaidu {
    if (!AutoPaginationBaidu.instance) {
      AutoPaginationBaidu.instance = new AutoPaginationBaidu()
    }
    return AutoPaginationBaidu.instance
  }

  /**
   * 检查搜索结果是否为空
   */
  checkPage(): boolean {
    if (HOSTNAME !== SUPPORTED_PLATFORMS.BAI_DU)
      return false

    const config: Partial<Record<BaiduPageType, {
      emptySelector: string
    }>> = {
      [BaiduPageType.Web]: {
        emptySelector: '#noresult',
      },
      [BaiduPageType.News]: {
        emptySelector: '#noresult',
      },
    }

    const pageConfig = config[this.pageType as BaiduPageType]

    if (!pageConfig)
      return false

    const $emptyElement = $(pageConfig.emptySelector)

    if ($emptyElement && $emptyElement.length === 1)
      return true

    return true
  }

  /**
   * 获取分页组件中链接的 usm 参数
   */
  getUsmFromPageItemLink(instance: AutoPagination): IBaiduSearchParams {
    const paramKeys: Array<keyof IBaiduWebSearchParams> | Array<keyof IBaiduNewsSearchParams> = this.pageType === BaiduPageType.Web
      ? Object.values(BaiduWebSearchParams)
      : Object.values(BaiduNewsSearchParams)

    const selector = instance.currentConfig.pageItemLink(instance)
    const $pageItemLink = $(selector)

    if (!$pageItemLink || $pageItemLink.length === 0) {
      logger.info(`[${this.name}] 无法识别分页链接元素：${selector}`)
      return this.defaultSearchParam as IBaiduSearchParams // 返回副本避免引用问题
    }

    const urlPath = $pageItemLink.first().attr('href')

    if (!urlPath) {
      logger.warn(`[${this.name}] 无法识别分页链接的 href 属性`)
      return this.defaultSearchParam as IBaiduSearchParams
    }

    const currentUrl = new URL(ToolKit.browser.url.getFullUrl(urlPath))

    return paramKeys.reduce((result: Record<string, string>, param) => {
      const key = param.toString()
      result[key] = currentUrl.searchParams.get(key) || this.defaultSearchParam?.[key as keyof IBaiduSearchParams] || ''
      return result
    }, {}) as IBaiduSearchParams
  }

  /**
   * 获取搜索参数
   */
  getSearchParams(): IBaiduSearchParams {
    return this.pageType === BaiduPageType.Web ? this.defaultWebSearchParams : this.defaultNewsSearchParams
  }

  /**
   * 生成百度搜索-网页的搜索参数
   * @param linkParams
   * @param searchKeyword
   * @param currentPage
   */
  generateBaiduWebSearchParams(linkParams: IBaiduWebSearchParams, searchKeyword: string, currentPage: number): Partial<Record<keyof IBaiduWebSearchParams, string>> {
    // 从当前 URL 提取关键参数
    const currentUrl = new URL(getCurrentURL())
    const params: Partial<Record<keyof IBaiduWebSearchParams, string>> = {
      [BaiduWebSearchParams.Wd]: linkParams.wd || searchKeyword, // 搜索关键词
      [BaiduWebSearchParams.Base_query]: linkParams.base_query || searchKeyword, // 搜索关键词
      [BaiduWebSearchParams.Pn]: (Math.max((currentPage - 1) * this.defaultResultNum, this.defaultResultNum)).toString(), // 搜索结果页码
      [BaiduWebSearchParams.Oq]: linkParams.oq || searchKeyword, // 搜索关键词
      [BaiduWebSearchParams.Ie]: linkParams.ie, // 默认编码
      [BaiduWebSearchParams.Usm]: linkParams.usm, // 排名偏移量
      [BaiduWebSearchParams.Rsv_pq]: linkParams.rsv_pq,
      [BaiduWebSearchParams.Rsv_t]: linkParams.rsv_t,
    }

    // 仅存在时才添加
    const optionCallbackParams = [BaiduWebSearchParams.Ch, BaiduWebSearchParams.Tn]
    optionCallbackParams.forEach((key) => {
      const value = linkParams[key] || currentUrl.searchParams.get(key)
      if (value)
        params[key] = value
    })

    // 必填参数而且需要放最后
    params.topic_pn = linkParams.topic_pn

    return params
  }

  /**
   * 生成百度搜索-网页的搜索参数
   * @param linkParams
   * @param searchKeyword
   * @param currentPage
   */
  generateBaiduNewsSearchParams(linkParams: IBaiduNewsSearchParams, searchKeyword: string, currentPage: number): Record<keyof IBaiduNewsSearchParams, string> {
    return {
      [BaiduNewsSearchParams.Wd]: linkParams.wd || searchKeyword,
      [BaiduNewsSearchParams.Word]: linkParams.word || searchKeyword,
      [BaiduNewsSearchParams.Tn]: linkParams.tn,
      [BaiduNewsSearchParams.Pn]: (Math.max((currentPage - 1) * this.defaultResultNum, this.defaultResultNum)).toString(), // 搜索结果页码
      [BaiduNewsSearchParams.Cl]: linkParams.cl,
      [BaiduNewsSearchParams.Ie]: linkParams.ie,
      [BaiduNewsSearchParams.Rtt]: linkParams.rtt,
      [BaiduNewsSearchParams.Bsst]: linkParams.bsst,
      [BaiduNewsSearchParams.Rsv_dl]: linkParams.rsv_dl,
      [BaiduNewsSearchParams.X_bfe_rqs]: linkParams.x_bfe_rqs,
      [BaiduNewsSearchParams.X_bfe_tjscore]: linkParams.x_bfe_tjscore,
      [BaiduNewsSearchParams.Tngroupname]: linkParams.tngroupname,
      [BaiduNewsSearchParams.NewVideo]: linkParams.newVideo,
      [BaiduNewsSearchParams.Goods_entry_switch]: linkParams.goods_entry_switch,
    }
  }
}
